/*
VOY A TENER QUE HACER UN VECTOR CON LA INFORMACION DE LOS PLANIFICADORES QUE SE CONECTEN: 
	* NOMBRE
	* SOCKET DE PLANIFICADOR
	* CANTIDAD DE ELEMENTOS EN COLA 
	* COLA DE PETICIONES
	
ADEMAS LAS PETICIONES DEBERA TENER COMO CAMPOS:
	* ID_DESCRIPTOR ( Para que cuando un planificador me responda algo sepa de que peticion es la respuesta ) 
	* SOCKET DE TERMINAL( El que realizo la peticion )
	* TIPO DE PETICION ( Lectura / Escritura ) 
	
		
*/
//BIBLIOTECAS
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <semaphore.h>
#include "ConfSock.h"
#include "TADComunicacion.h"
#include "funciones.h"



//VECTOR DE 10 POSICIONES CON LOS NOMBRES DE LOS "CLIENTES" DEL PFS  Y SU SOCKET DE RELACION
TClientes VectorClientes[10]; 
// VECTOR DE PLANIFICADORES PARA USO ASINCRONICO 
TPlanificador VectorP[10];
TColaW *ColaW;
char rutaconfig[256];
TColaG *ColaG;
int32_t CantC=-1,CantH=-1,CantS=-1,Prioridad=0;
t_log* log;
int32_t cantDisp=0,EstaLog;
fd_set read_fds;
int32_t EstaConsola;
int32_t pid;
pthread_mutex_t MutexEnvio;



int32_t main(int32_t argv , char* argc[]){
	/***********************************************************************************/
	/************************         VARIABLES                     *******************/
	/***********************************************************************************/

	void *FunPetic(void*);
	void* FunDesc(void);
	int32_t i,listener,newfd=0,fdmax,addrlen,EstaP,ret=2,poss=0,flagg=0,cantPlanif;
	int32_t CantF,bytesRec=0,nnn=0,flag2=0,pos=0,j=0;
	TNodoG *NodoG;
	TNodoW *NodoW;
	TMensaje *TheirM;
	TInfo *Info;
	pthread_t Hilo;
	char numero[10];
	struct sockaddr_in remoteaddr;
	if(argv != 2){
		printf("Error en los parametros\n");
		return 1;
	}
	memset(rutaconfig,'\0', sizeof(rutaconfig));
	memcpy(rutaconfig,argc[1],strlen(argc[1]));


	/******************************************************************************************/
	pthread_mutex_init(&MutexEnvio,NULL);
	ColaG=(TColaG*)calloc(1,sizeof(TColaG));
	ColaW=(TColaW*)calloc(1,sizeof(TColaW));
	EstaLog = logActivado();
	log = log_create("RAID", "log.txt", DEBUG | INFO | WARNING, M_CONSOLE_ENABLE);
	EstaConsola=consolaActivada();

	pid=(int32_t)getpid();

	

	if(EstaConsola){
		printf("--------------------------------------------------------------------------------\n");
		printf("--                   Bienvenido al Sistema RAID                              --\n");
		printf("--------------------------------------------------------------------------------\n\n\n");
	}
	
	//Levanto Socket de escucha Listener
	listener = CListen();
	memset(numero,'\0',10);
	//INICIALIZO VECTORES 
	for(i=0;i<10;i++){
		VectorClientes[i].Sock= -1;
		VectorP[i].Sincro = 0;
	    VectorP[i].Sock= -1;
		VectorP[i].Prioridad=0;
		VectorP[i].CantSincro=0;
	
	}
	fdmax=listener;
	cantDisp=0;
	cantPlanif=0;
	EstaP=0;
	CantF=0;
	while(1){
		FD_ZERO(&read_fds);	
		FD_SET(listener, &read_fds);
		
		//Agrego los "Terminales" atraves del Vector de  Terminales
		for(i=0;i<10;i++){
			if(VectorClientes[i].Sock !=  -1){
				//Obtenemos el fdmax comparando quien es el socket con valor mas grande
				if(VectorClientes[i].Sock > fdmax){
					fdmax = VectorClientes[i].Sock;
				}
				FD_SET(VectorClientes[i].Sock, &read_fds);	
			}
		}
		/**************************   Select ***********************/
		if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){
			if(EstaLog)
				log_error(log, "RAID", "Message error: %s", "Fallo el Select");
		}
		
		for(i=0; i <= fdmax; i++){
			if(FD_ISSET(i, &read_fds)){ 	
				if(i==listener){ 	
					/*
					SE CONECTO ALGUIEN NUEVO ENTONCES:
						* Hacemos HandShake 
						* Si  sale bien lo agregamos a new_fd al vector que corresponda  con la informacion necesaria
						* Si es  un nuevo Planificador debemos levantar un Thread para luego enviarle las peticiones
						  al mismo cuando sea necesario.
						*/
					addrlen = sizeof(remoteaddr);
					while(newfd<=0){
						newfd = (int32_t)accept(listener, (struct sockaddr*)&remoteaddr,&addrlen);
					}	
					ret=HandShakeReceptor(newfd,cantDisp ,1,cantPlanif,&CantC,&CantH,&CantS);
					if(ret==1){	
						Info=ObtenerNombre(newfd);
						if(EstaLog)
							log_info(log, "RAID", "Message info: Se conecto %s de tipo %c", Info->Nombre,Info->Tipo);
						if(Info->Tipo  == 'P'){
							pos=0;
							while( VectorP[pos].Sock != -1) 
								pos++;
							
							if(flag2 == 0){
								if(EstaLog)
									log_info(log, "RAID", "Message info: %s", "RAID en estado ACTIVO");
								flag2=1;
							}
							if(cantPlanif == 0){ // El maestro no debe sincronizarse con el nadie porque ... es el MAESTRO!
								VectorP[pos].Sincro = 1;
								//pthread_create(&Hilo, NULL, FunDesc, NULL);
							}	
							if(EstaConsola)
								printf("Se conecto el Planificador %s\n",Info->Nombre);
							memcpy(VectorP[pos].Nombre,Info->Nombre,20);
							VectorP[pos].Sock=newfd;
							VectorP[pos].CantPetic=0;
							VectorP[pos].Cola=(TColaPetic*)calloc(1,sizeof(TColaPetic));
							VectorP[pos].ColaW=(TColaW*)calloc(1,sizeof(TColaW));
							pthread_create(&Hilo, NULL, FunPetic, (void*)pos);
							pthread_mutex_init( &VectorP[pos].Mutex,NULL);
							pthread_mutex_init(&VectorP[pos].MutexW,NULL);
							sem_init(&VectorP[pos].Sem,0,0);
							sem_init(&VectorP[pos].ParaSincro,0,0);
							cantPlanif++;
														
						}
						if(Info->Tipo == 'F'){
							poss=0;
							while(VectorClientes[poss].Sock != -1)
								poss++;
							memcpy(VectorClientes[poss].Nombre,Info->Nombre,20);
							VectorClientes[poss].Sock=newfd;
							CantF++;
							
						}
						cantDisp++;
						newfd=0;
						free(Info);
						
						
					}
					else{ // Error al tratar de hacer HandShake
						close(newfd);
						newfd=0;
						
					}
							
				}			
				else{				//Un PFS me envio una Peticion
	
						
						TheirM=(TMensaje*)calloc(1,sizeof(TMensaje));
						bytesRec=-1;
						while(bytesRec<0){
							bytesRec=recv(i, (void*)TheirM, sizeof(struct TMensaje), MSG_WAITALL);  // RECIBO REQUEST
						}	
						if(bytesRec == 0){
							cantDisp--;
							if(EstaLog)
								log_info(log, "RAID", "Message info: Se desconecto un terminal");
							poss=0;
							while(VectorClientes[poss].Sock != i)
								poss++;
							VectorClientes[poss].Sock = -1;
							memset(VectorClientes[poss].Nombre,'\0',20);
							bytesRec=-1;
						}	
						else{
							bytesRec=-1;
							if(EstaLog)
								log_info(log, "RAID", "Message info: Recibi del PFS: %s", TheirM->payload);
							if(TheirM->payloadDescriptor == '1'){
								flagg = 0;	
								for(nnn=0;nnn<10;nnn++){
									if((VectorP[nnn].Sincro == 0)&&(VectorP[nnn].Sock != -1)){
										flagg = 1;
									}	
									
								}
								NodoG=(TNodoG*)calloc(1,sizeof(TNodoG));
								memcpy(NodoG->idDescriptor,TheirM->idDescriptor,16);
								NodoG->Enviada=0;
									for(nnn= 0 ; nnn < 10 ; nnn++){
									if(VectorP[nnn].Sock != -1 && VectorP[nnn].Sincro == 1)
										NodoG->Enviada++;
								}
									meternodoG(ColaG, NodoG ); //Meto la peticion en Cola General con Cargada=0 y Enviada = Cantidad de Planificadores Sincronizados
									free(NodoG);

								if(	flagg == 1){ 
								
									DistribucionPrioridad(VectorP,TheirM->payload,TheirM->payloadDescriptor,i,TheirM->idDescriptor);
									NodoW=(TNodoW*)calloc(1,sizeof(TNodoW));
									memcpy(NodoW->idDescriptor,TheirM->idDescriptor,16);
									memcpy(NodoW->payload,TheirM->payload,1100);
									for( j=0;j<10;j++){
										if((VectorP[j].Sock != -1) && ( VectorP[j].Sincro == 0))
											pthread_mutex_lock(&VectorP[j].MutexW);
											meternodoW(VectorP[j].ColaW, NodoW );
											pthread_mutex_unlock(&VectorP[j].MutexW);
									}		
									free(NodoW);
								}
								else 
									Distribucion(VectorP,TheirM->payload,TheirM->payloadDescriptor,i,TheirM->idDescriptor);
							}
							else{ //Es una lectura
								flagg=0;
								for(nnn=0;nnn<10;nnn++){
										if((VectorP[nnn].Sincro == 0)&&(VectorP[nnn].Sock != -1)){
											flagg = 1;
										}	
										
								}
								
								if(	flagg == 1){ 
									DistribucionPrioridad(VectorP,TheirM->payload,TheirM->payloadDescriptor,i,TheirM->idDescriptor);
								}
								else	
									Distribucion(VectorP,TheirM->payload,TheirM->payloadDescriptor,i,TheirM->idDescriptor);
							}
								if(EstaLog)
									log_info(log, "RAID", "Message info: %s","Peticion cargada correctamente en Colas Planificadores");
						}
						free(TheirM);
				}
			}
		}
	}
	return 0;
}


 /*
 Funcion del Thread que se fija si tiene peticiones en su cola y las envia al PPD
 y cuando el mismo responde carga la cola con la respuesta

 Cuando envio una peticion debo enviar en el payloadDescriptor '1' si es escritura o '0' si es de lectura
 Payload :      "write(23,holacomoestas)"
 Payload :      "read(23)"
 */
void *FunPetic(void* PosVec){
	TNodoCola *punt,*ant,*punt2;
	TNodoG *NodoG;
	ent n=0,bytesRec=-1,flag = 0,i=0,Sock,nn=0,number=0,largo=0,nnn=0,CantSecTot=0,ii=0,EsPlanif=0,Posicion=0,HayP=0;
	char numero[20],Tema[16], respuesta[512],cad[50],peticion[1100];
	time_t tActual;
	int32_t numSock,Desc=0;
	TNodoCola *element;
	time_t tiempo = time(0);
	char output[128];
    struct tm *tlocal = localtime(&tiempo);
	char llamada[20];
	struct tm* tiempoGenerico;
	TMensaje *TheirM,*MyM,*MyM2,*OtroMensaje,*Mensaje;
	TNodoW *NodoW,*antW;
	memset(peticion,'\0',1100);
	memset(llamada,'\0',20);
	memset(output,'\0',128);

	if(VectorP[(ent)PosVec].Sincro == 0 ){
		if(EstaConsola)
			printf("Sincronizando planificador %s con los demas discos sincronizados \n",VectorP[(ent)PosVec].Nombre);
		CantSecTot = ( CantC*CantS);

		nn=0;
		ii=0;
		strftime(output,128,"%H:%M:%S",tlocal);
		if(EstaConsola)
			printf("Hora de Comienzo de Sincronizacion %s\n",output);

		Mensaje=(TMensaje*)calloc(1,sizeof(TMensaje));
		while(nn < CantSecTot ){
			ii=0;
			while(ii < 1500 ){
				for(i=0;i<10;i++){

					if(VectorP[(ent)PosVec].Sock == -1){
						if(EstaLog)
							log_info(log, "RAID", "Message info: Se desconecto el planificador %s mientras se sincronizaba\n",VectorP[(ent)PosVec].Nombre);
							printf("Se desconecto el planificador %s mientras se sincronizaba\n",VectorP[(ent)PosVec].Nombre);
						free(VectorP[(ent)PosVec].Cola);
						free(VectorP[(ent)PosVec].ColaW);
						pthread_exit(NULL);
					}

					if((VectorP[i].Sock != -1) && (VectorP[i].Sincro==1) ){
						memset(peticion,'\0',1100);
						sprintf(peticion,"read(%d)",nn);
						tActual = time(NULL);
						tiempoGenerico = localtime(&tActual);
						strftime(cad, 50, "%H%M%S", tiempoGenerico);
						sprintf(Tema,"%s%010i",cad,rand()); // OBTENGO ASUNTO RANDOM
						element=(TNodoCola*)calloc(1,sizeof(TNodoCola));
						memcpy(element->idDescriptor,Tema,16);
						element->SocketT=VectorP[(ent)PosVec].Sock;
						element->TipoPeticion='0';
						memset(element->Peticion,'\0',1100);
						memcpy(element->Peticion,peticion,1100);
						element->EstaProcesado=0;
						element->enviado=0;
						pthread_mutex_lock(&VectorP[i].Mutex);
						meternodo(VectorP[i].Cola, element );
						VectorP[i].CantPetic++;
						VectorP[(ent)PosVec].CantSincro++;
						pthread_mutex_unlock(&VectorP[i].Mutex);
						sem_post(&VectorP[i].Sem);
						free(element);
						nn++;
					}
					if(nn == CantSecTot)
						break;

				}
				if(nn == CantSecTot)
					break;
				else
					ii++;
			}
			//sleep(2);
			sem_wait(&VectorP[(ent)PosVec].ParaSincro);
			


		}

			memset(output,'\0',128);
			tiempo = time(0);
			tlocal = localtime(&tiempo);
			strftime(output,128,"%H:%M:%S",tlocal);
			if(EstaConsola)
				printf("Hora de finalizacion de Sincronizacion %s\n",output);
			free(Mensaje);
			VectorP[(ent)PosVec].Sincro = 1;
			if(EstaConsola)
				printf("Planificador %s sincronizado correctamente\n",VectorP[(ent)PosVec].Nombre);
			pthread_mutex_lock(&VectorP[(ent)PosVec].MutexW);
			NodoW = VectorP[(ent)PosVec].ColaW->Head;
			while(NodoW != NULL){
				MyM2=(TMensaje*)calloc(1,sizeof(TMensaje));
				memcpy(MyM2->idDescriptor , NodoW->idDescriptor,16);
				memcpy(MyM2->payload,NodoW->payload,1100);
				MyM2->payloadLength =512;
				MyM2->payloadDescriptor = '1';
				send(VectorP[(ent)PosVec].Sock,(void*)MyM2,sizeof(struct TMensaje),0); //ENVIO RESPONSE
				free(MyM2);
				OtroMensaje=(TMensaje*)calloc(1,sizeof(TMensaje));
				bytesRec= -1;
				memset(OtroMensaje->idDescriptor,'\0',16);
				memset(OtroMensaje->payload,'\0',1100);
				while(bytesRec<0){
					  bytesRec=recv(VectorP[(ent)PosVec].Sock, (void*)OtroMensaje, sizeof(struct TMensaje), MSG_WAITALL);  // RECIBO REQUEST
				}
				if(bytesRec == 0){
					cantDisp--;
					close(VectorP[(ent)PosVec].Sock);
					VectorP[(ent)PosVec].Sock = -1;
					memset(VectorP[(ent)PosVec].Nombre, '\0', 20);
					VectorP[(ent)PosVec].CantPetic = 0;
					VectorP[(ent)PosVec].CantSincro=0;
					VectorP[(ent)PosVec].Sincro = 0;
					free(VectorP[(ent)PosVec].Cola);
					free(VectorP[(ent)PosVec].ColaW);
					pthread_exit(NULL);
				}
				free(OtroMensaje);
				antW = NodoW;
				NodoW = NodoW->Next;
				ColaW =eliminarNodoW( ColaW, antW);
			}
			pthread_mutex_unlock(&VectorP[(ent)PosVec].MutexW);


	}
	n=0;
	while(1){
		//Chequeo si hay peticiones en mi Cola de Peticiones

		sem_wait(&VectorP[(ent)PosVec].Sem);
		pthread_mutex_lock(&VectorP[(ent)PosVec].Mutex);
			punt = VectorP[(ent)PosVec].Cola->Head;
			while(punt != NULL){ //Me fijo si hay alguno peticion NO ENVIADA en la cola del planificador
				if(punt->enviado == 0){
					//CARGO MyM y lo envio a el Planificador del Thread
					MyM=(TMensaje*)calloc(1,sizeof(TMensaje));
					memcpy(MyM->idDescriptor,punt->idDescriptor,16);
					memcpy(MyM->payload,punt->Peticion,1100);
					MyM->payloadDescriptor=punt->TipoPeticion;
					MyM->payloadLength=strlen(punt->Peticion);//VER
					send(VectorP[(ent)PosVec].Sock,(void*)MyM,sizeof(struct TMensaje),0);
					free(MyM);
					punt->enviado = 1;
					n++;
				}

				if(VectorP[(ent)PosVec].Prioridad){
					punt = VectorP[(ent)PosVec].Cola->Head;
					VectorP[(ent)PosVec].Prioridad=0;
					if(EstaLog)
						log_info(log, "ThreadPlanif", "Message info: %s","Prioridad activada:Atendiendo peticiones del PFS");
				}
				else
					punt = punt->Next;

			}


		pthread_mutex_unlock(&VectorP[(ent)PosVec].Mutex);
		if(n > 0){
			n--;
			bytesRec=-1;
			TheirM=(TMensaje*)calloc(1,sizeof(TMensaje));
			memset(TheirM->idDescriptor,'\0',16);
			memset(TheirM->payload,'\0',1100);
				bytesRec=-1;
				while(bytesRec < 0 ){
					bytesRec=recv(VectorP[(ent)PosVec].Sock, (void*)TheirM, sizeof(struct TMensaje), MSG_WAITALL);
				}


			if(bytesRec == 0){
				Sock= VectorP[(ent)PosVec].Sock;
				cantDisp--;
				if(EstaLog)
					log_info(log, "ThreadPlanif", "Message info: Se desconecto el Planificador %s",VectorP[(ent)PosVec].Nombre);
				printf("Se desconecto el Planificador %s",VectorP[(ent)PosVec].Nombre);
				HayP=0;
				for(i=0;i<10;i++){
					if((VectorP[i].Sock != -1) && (VectorP[i].Sincro==1) )
						HayP++;
				}
				if(HayP == 1){
					printf("No hay mas Discos Sincronizados..\n|--  El Proceso RAID ha finalizado --| \n");
					sprintf(llamada,"kill -9 %d",pid);
					system(llamada);
				}
				//Lo tengo que sacar de el vector de planificadores

				VectorP[(ent)PosVec].Sock = -1;
				memset(VectorP[(ent)PosVec].Nombre, '\0', 20);
				VectorP[(ent)PosVec].CantPetic = 0;
				VectorP[(ent)PosVec].Sincro = 0;
				VectorP[(ent)PosVec].CantSincro=0;

				//Tengo que redistribuir sus peticiones
				pthread_mutex_lock(&VectorP[(ent)PosVec].Mutex);
				punt= VectorP[(ent)PosVec].Cola->Head;

				if(EstaLog && punt != NULL)
					if(EstaLog)
						log_info(log, "ThreadPlanif", "Message info: %s","Redistribucion de pedidos de planificador %s\n",VectorP[(ent)PosVec].Nombre);
				while(punt != NULL){
					if(punt->TipoPeticion == '0')
						Distribucion(VectorP,punt->Peticion,punt->TipoPeticion,punt->SocketT,punt->idDescriptor);
					else{

						NodoG= ColaG->Head;
						flag=0;
						while(strncmp(punt->idDescriptor,NodoG->idDescriptor,16)){
							NodoG = NodoG->Next;
							if(NodoG == NULL)
									break;
						}
						NodoG->Enviada--;
					}
					ant = punt;
					punt = punt->Next;
					free(ant);
				}
				pthread_mutex_unlock(&VectorP[(ent)PosVec].Mutex);
				// Tengo que cerrar el thread
				free(VectorP[(ent)PosVec].Cola);
				free(VectorP[(ent)PosVec].ColaW);
				close(VectorP[(ent)PosVec].Sock);
				pthread_exit(NULL);
			}
			else{


				if(EstaLog)
					log_info(log, "ThreadPlanif", "Message info: Recibi del Planificador %s",TheirM->payload);
				pthread_mutex_lock(&VectorP[(ent)PosVec].Mutex);
				punt = VectorP[(ent)PosVec].Cola->Head;
				while(strncmp(punt->idDescriptor,TheirM->idDescriptor,16)){
					punt = punt->Next;
					if(punt== NULL)
						break;
				}
				if(punt==NULL){
					if((ent)PosVec == 0){
						punt = VectorP[1].Cola->Head;
					}
					else{
						punt = VectorP[0].Cola->Head;
					}
					while(strncmp(punt->idDescriptor,TheirM->idDescriptor,16)){
						punt = punt->Next;
						if(punt== NULL)
							break;
					}

				}
				
				/**********************************************/
				//Para mostrar como funciona algoritmo
				if(EstaConsola == 2 ){

					int32_t EsP=0;
					for(i=0;i<10;i++){
						if(VectorP[i].Sock == punt->SocketT)
							EsP =1;
					}
					if(!EsP)
						printf("Recibi respuesta de peticion %s\n",punt->Peticion);
				}		



				/**********************************************/
				VectorP[(ent)PosVec].CantPetic--;

				pthread_mutex_unlock(&VectorP[(ent)PosVec].Mutex);
				if(punt->SocketT != -1){
					if(punt->TipoPeticion == '1'){
						NodoG= ColaG->Head;

						flag=0;

						while(strncmp(punt->idDescriptor,NodoG->idDescriptor,16)){
							NodoG = NodoG->Next;
							if(NodoG == NULL)
								break;
						}

						if(EstaLog)
							log_info(log, "ThreadPlanif", "Message info: Se realizo la escritura correctamente en el Disco %s %d",VectorP[(ent)PosVec].Nombre,PosVec);
							NodoG->Enviada--;
							if(NodoG->Enviada==0){ //Si ya lo envie al PFS no lo envio de nuevo
								//Envio al PFS la respuesta
								//pthread_mutex_lock(&MutexEnvio);
								send(punt->SocketT,(void*)TheirM,sizeof(struct TMensaje),0);
								//pthread_mutex_unlock(&MutexEnvio);
								eliminarNodoG( ColaG , NodoG);
							}

					}

					if(punt->TipoPeticion == '0'){
						nnn=0;
						if(VectorP[(ent)PosVec].Sincro == 1){
							nnn=0;
							for( nnn =0; nnn < 10 ; nnn++){
								if(VectorP[nnn].Sock == punt->SocketT){
									EsPlanif=1;
									Posicion= nnn;

									nn=0;
									while(punt->Peticion[nn] != '(')
										nn++;
									nn++;
									i=0;
									memset(numero,'\0',20);
									while(punt->Peticion[nn] != ')'){
										numero[i] = punt->Peticion[nn];
										nn++;
										i++;
									}
									number = atoi(numero);
									memset(respuesta,'\0',512);
									memcpy(respuesta,TheirM->payload,512);
									memset(TheirM->payload,'\0',1100);
									sprintf(TheirM->payload,"write(%d,",number);
									largo = strlen(TheirM->payload);
									memcpy(TheirM->payload+largo,respuesta , 512);
									memcpy( TheirM->payload+largo + 512, ")" ,1);
									pthread_mutex_lock(&VectorP[nnn].Mutex);
									VectorP[nnn].CantSincro--;
									pthread_mutex_unlock(&VectorP[nnn].Mutex);

									if(VectorP[nnn].CantSincro == 0 ){
										sem_post(&VectorP[nnn].ParaSincro);

									}

								}

							}
						}

						if(EstaLog)
							log_info(log, "ThreadPlanif", "Message info: Se realizo la lectura correctamente en el Disco %s %d",VectorP[(ent)PosVec].Nombre,PosVec);
						pthread_mutex_lock(&MutexEnvio);
						bytesRec=send(punt->SocketT,(void*)TheirM,sizeof(struct TMensaje),0);
						pthread_mutex_unlock(&MutexEnvio);

						if(bytesRec <= 0){
							if(EsPlanif){
								EsPlanif=0;
								Desc=1;
								cantDisp--;
								if(EstaLog)
									log_error(log, "ThreadPlanif", "Message info:Se desconecto el PPD que se encontraba en estado de Sincronizacion");

								numSock= VectorP[Posicion].Sock;
								close(VectorP[Posicion].Sock);

								VectorP[Posicion].Sock = -1;
								memset(VectorP[Posicion].Nombre, '\0', 20);
								VectorP[Posicion].CantPetic = 0;
								VectorP[Posicion].Sincro = 0;
								VectorP[Posicion].CantSincro=0;
								VectorP[Posicion].Prioridad=0;
								pthread_mutex_lock(&VectorP[(ent)PosVec].Mutex);
								punt2= VectorP[(ent)PosVec].Cola->Head;
								while(punt2 != NULL){
									if(punt2->SocketT ==  numSock)
										punt->SocketT= -1;
									punt2= punt2->Next;
								}
								pthread_mutex_unlock(&VectorP[(ent)PosVec].Mutex);

							}
						}


					}
				}
				//Eliminar nodo de cola de planificador
				pthread_mutex_lock(&VectorP[(ent)PosVec].Mutex);
				VectorP[(ent)PosVec].Cola = eliminarNodo( VectorP[(ent)PosVec].Cola, punt);
				pthread_mutex_unlock(&VectorP[(ent)PosVec].Mutex);

			}
			free(TheirM);
		}
	}
	return 0;
}




